home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / telecom / 107 / c / cspiff.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-02-20  |  21.4 KB  |  457 lines

  1. /****************************************************************************/
  2. /*                                                                          */
  3. /* Module:     cspiff.c - neaten the appearance of C source files.          */
  4. /*                                                                          */
  5. /* Programmer: George R. Woodside                                           */
  6. /*                                                                          */
  7. /* Date:       October 25, 1986                                             */
  8. /*                                                                          */
  9. /* Flags:      -i file     Specify name of input file.                      */
  10. /*                         Default is stdin.                                */
  11. /*                         (If a parameter appears with no flag, it         */
  12. /*                         is accepted as the name of the input file.)      */
  13. /*             -o file     Specify name of output file.                     */
  14. /*                         Default is stdout.                               */
  15. /*             -l int      Set left margin for aligning comments.           */
  16. /*                         Default is column 40.                            */
  17. /*             -r int      Set right margin for aligning comments.          */
  18. /*                         Default is column 78.                            */
  19. /*             -t int      Set tab (indentation) value.                     */
  20. /*                         Default is 2 columns.                            */
  21. /*                                                                          */
  22. /****************************************************************************/
  23.  
  24. /****************************************************************************/
  25. /*                                                                          */
  26. /* Line types:                                                              */
  27. /*      (In line types, the symbol 'b' represents a blank space.)           */
  28. /*                                                                          */
  29. /*  Full width comment line:                                                */
  30. /*      Starts in first column with /**                                     */
  31. /*                                                                          */
  32. /*  Left aligned comment line:                                              */
  33. /*      Starts in first column with /*b                                     */
  34. /*                                                                          */
  35. /* Indented full width comment line:                                        */
  36. /*      Starts with /** in any column other than the first.                 */
  37. /*                                                                          */
  38. /* Indented comment line:                                                   */
  39. /*      Starts with /*b in any column other than the first.                 */
  40. /*      Or follows a non-terminated comment line.                           */
  41. /*                                                                          */
  42. /* Normal code line:                                                        */
  43. /*      starts in the same column as the previous code line.                */
  44. /*                                                                          */
  45. /* Indentation Increase code line:                                          */
  46. /*      starts in any column further in than the previous code line.        */
  47. /*                                                                          */
  48. /* Indentation Decrease code line:                                          */
  49. /*      starts in any column further out than the previous code line.       */
  50. /*                                                                          */
  51. /****************************************************************************/
  52.  
  53. #include <stdio.h>
  54.  
  55. #define MAXLINE 256                     /* width of a program line          */
  56. #define BLANK    0                      /* blank line                       */
  57. #define FCOMM    1                      /* comment: full width              */
  58. #define LCOMM    2                      /* comment: left aligned            */
  59. #define IFCOMM   3                      /* comment: indented full width     */
  60. #define ICOMM    4                      /* comment: indented                */
  61. #define CCOMM    5                      /* comment: continued across lines  */
  62. #define CODE     6                      /* code: aligned                    */
  63. #define ICODE    7                      /* code: indentation increase       */
  64. #define OCODE    8                      /* code: indentation decrease       */
  65. #define O2CODE   9                      /* code: decrease indentation twice */
  66. #define ZCODE   10                      /* code: left aligned               */
  67.  
  68. extern char   *optarg;                  /* argument pointer                 */
  69. extern int    optind;                   /* index of unprocessed argument    */
  70.  
  71. char   iline[MAXLINE+1];                /* input line                       */
  72. char   oline[MAXLINE+1];                /* output line                      */
  73. char   *pname = "cspiff";               /* program name                     */
  74.  
  75. char   *infile;                         /* input file name                  */
  76. char   *outfile;                        /* output file name                 */
  77.  
  78. int    left  = 40;                      /* left alignment of comments       */
  79. int    right = 78;                      /* right alignment of comments      */
  80. int    tab   = 2;                       /* indentation value                */
  81. int    prior[32];                       /* start of prior line addresses    */
  82. int    pindex = 0;                      /* start of prior line array index  */
  83. int    lowest;                          /* lowest position with data        */
  84. int    highest;                         /* highest position with data       */
  85. int    align;                           /* code alignment position          */
  86. int    i_flag = 0;                      /* input file present flag          */
  87. int    o_flag = 0;                      /* output file present flag         */
  88. int    c_flag = 0;                      /* processing continued comment     */
  89.  
  90. main(argc,argv)
  91. int     argc;
  92. char    *argv[];
  93. {
  94.   FILE   *fp_in;
  95.  
  96.   register  int  c;                     /* input byte                       */
  97.  
  98.  /***************************************************************************/
  99.  /*                                                                         */
  100.  /* If unix system, save program name.                                      */
  101.  /*                                                                         */
  102.  /***************************************************************************/
  103.  
  104. #ifdef UNIX
  105.   pname = argv[0];                      /* name is always first parameter.  */
  106. #endif
  107.  
  108.   if(argc < 2)
  109.     {
  110.       printf("Usage: %s -i file -l int -r int -o file -t int\n",pname);
  111.       printf("\t-i file   = input file name\n");
  112.       printf("\t-l int    = left alignment of comments\n");
  113.       printf("\t-r int    = right alignment of comments\n");
  114.       printf("\t-o file   = output file name\n");
  115.       printf("\t-t file   = indentation tab value\n");
  116.       exit(1);
  117.     }
  118.  
  119.   while((c=getopt(argc,argv,"I:L:R:O:T:i:l:r:o:t:")) != EOF)
  120.     {
  121.       switch (c)
  122.         {
  123.           case('I'):
  124.           case('i'):
  125.             i_flag = 1;                 /* show file named                  */
  126.             infile = optarg;            /* input file name                  */
  127.             break;
  128.  
  129.           case('L'):
  130.           case('l'):
  131.             left = atoi(optarg);        /* left alignment                   */
  132.             break;
  133.  
  134.           case('R'):
  135.           case('r'):
  136.             right = atoi(optarg);       /* right alignment                  */
  137.             break;
  138.  
  139.           case('O'):
  140.           case('o'):
  141.             o_flag = 1;                 /* show name is set                 */
  142.             outfile = optarg;           /* input file name                  */
  143.             break;
  144.  
  145.           case('T'):
  146.           case('t'):
  147.             tab = atoi(optarg);         /* indentation value                */
  148.             break;
  149.  
  150.  
  151.         }                               /* end switch                       */
  152.       }                                 /* end while                        */
  153.  
  154.  
  155.       while(optind != argc)             /* if leftover arguments,           */
  156.         {
  157.           if(i_flag == 0)
  158.             {
  159.               infile = argv[optind++];
  160.               i_flag = 1;
  161.             }
  162.  
  163.           else
  164.             printf("%s: Unknown argument: %s\n",pname,argv[optind++]);
  165.  
  166.         }                               /* end while                        */
  167.  
  168.       if(i_flag)
  169.         {
  170.           if( (fp_in = fopen(infile,"r") ) == NULL)
  171.             {
  172.               printf("%s: Unable to open input file %s\n",pname,infile);
  173.               exit(1);
  174.             }                           /* end open error                   */
  175.           else
  176.             spiffo(fp_in);              /* do the file                      */
  177.  
  178.         }                               /* end if i_flag                    */
  179.       else
  180.         spiffo(stdin);                  /* do standard in                   */
  181.  
  182. }                                       /* end main                         */
  183.  
  184. /****************************************************************************/
  185. /*                                                                          */
  186. /* Now we try to open the output file if needed                             */
  187. /*                                                                          */
  188. /****************************************************************************/
  189.  
  190. spiffo(fin)
  191. FILE  *fin;
  192. {
  193.   FILE  *fout;
  194.  
  195.   if(o_flag)
  196.     {
  197.       if( (fout = fopen(outfile,"w") ) == NULL)
  198.         {
  199.           printf("%s: Unable to open output file %s\n",pname,outfile);
  200.           exit(1);
  201.         }                               /* end open error                   */
  202.       else
  203.         spiff(fin,fout);                /* do the file                      */
  204.  
  205.     }                                   /* end if o_flag                    */
  206.   else
  207.     spiff(fin,stdout);                  /* do standard out                  */
  208.  
  209. }
  210.  
  211. /****************************************************************************/
  212. /*                                                                          */
  213. /* Now we process the file                                                  */
  214. /*                                                                          */
  215. /****************************************************************************/
  216.  
  217. spiff(ifp,ofp)
  218. FILE  *ifp;
  219. FILE  *ofp;
  220. {
  221.  
  222.   int    type;                          /* type of line it is               */
  223.  
  224.   prior[0] = 0;                         /* insure initial alignment         */
  225.  
  226.   while( fgets(iline,MAXLINE -1,ifp) != NULL)
  227.   {
  228.     type = test(oline,iline);           /* get the line type                */
  229.     process(type,iline,oline,ofp);      /* process it                       */
  230.   }                                     /* end while we read a line         */
  231.  
  232.   fclose(ifp);                          /* close input file                 */
  233.   fclose(ofp);                          /* and the output                   */
  234. }                                       /* end spiff                        */
  235.  
  236. /****************************************************************************/
  237. /*                                                                          */
  238. /* determine the type of a program line                                     */
  239. /*                                                                          */
  240. /****************************************************************************/
  241.  
  242. test(linetmp,line)
  243. char  line[];
  244. char  linetmp[];
  245. {
  246.  
  247.   int c;
  248.   int length = 0;
  249.  
  250.   if( detab(linetmp,line) == 0 )        /* if no data in line,              */
  251.     return(BLANK);                      /* call it blank                    */
  252.  
  253.   if(c_flag)                            /* if old comment did not end,      */
  254.     return(CCOMM);                      /* then continued comment           */
  255.  
  256.   lowest = -1;                          /* no data found yet                */
  257.  
  258.   while( (c = linetmp[length]) != NULL)
  259.     {
  260.  
  261.       if( c != ' ')
  262.         {
  263.           if(lowest == -1)
  264.             lowest = length;            /* save left position               */
  265.           highest = length;             /* save the address                 */
  266.         }                               /* end not space                    */
  267.  
  268.       length++;                         /* and move up                      */
  269.  
  270.     }                                   /* end while not end of line        */
  271.  
  272.  
  273.   if(linetmp[lowest] == '/')
  274.     {
  275.       if(linetmp[lowest+1] == '*')
  276.         {
  277.           if(linetmp[lowest+2] == '*')
  278.             {
  279.               if(lowest == 0)
  280.                 return(FCOMM);          /* left aligned full width comment  */
  281.               else
  282.                 return(IFCOMM);         /* indented full width comment      */
  283.             }                           /* end third character is asterisk  */
  284.           if(lowest == 0)
  285.             return(LCOMM);              /* left aligned comment line        */
  286.           else
  287.             return(ICOMM);              /* indented comment line            */
  288.         }                               /* end second character is asterisk */
  289.     }                                   /* end first character is slash     */
  290.  
  291.   if(lowest == 0)
  292.     {
  293.       pindex    = 0;                    /* force outer level                */
  294.       prior[0]  = 0;                    /* reset current value              */
  295.       return(ZCODE);                    /* and show at left margin          */
  296.     }
  297.  
  298.   if(lowest < prior[pindex])
  299.     {
  300.       if(lowest < prior[pindex-1])
  301.         {
  302.           while(lowest < prior[pindex] )
  303.             pindex--;
  304.           prior[pindex] = lowest;       /* save new address                 */
  305.           return(O2CODE);               /* and show out 2 levels            */
  306.         }
  307.       else
  308.         {
  309.           while(lowest < prior[pindex] )
  310.             pindex--;
  311.           prior[pindex] = lowest;       /* save new address                 */
  312.           return(OCODE);                /* code, decrease indentation       */
  313.         }
  314.     }
  315.  
  316.   if(lowest > prior[pindex])
  317.     {
  318.       prior[++pindex] = lowest;         /* save new address                 */
  319.       return(ICODE);                    /* code, increase indentation       */
  320.     }
  321.   else
  322.     return(CODE);                       /* code, aligned                    */
  323.  
  324. }                                       /* end test line type               */
  325.  
  326. /****************************************************************************/
  327. /*                                                                          */
  328. /* Expand tabs to eight position spaces,                                    */
  329. /* remove carriage returns and newlines, if any,                            */
  330. /* and return count of data characters in line.                             */
  331. /*                                                                          */
  332. /****************************************************************************/
  333.  
  334. detab(work,in)
  335. char   in[];
  336. char   work[];
  337. {
  338.   register int from = 0;
  339.   register int to   = 0;
  340.   register int i    = -1;
  341.   register int c;
  342.  
  343.   while( c = in[from++] )
  344.     {
  345.       switch (c)
  346.         {
  347.           case '\t':                    /* for a tab,                       */
  348.             do {
  349.               work[to++] = ' ';         /* stuff a space                    */
  350.               } while ( to & 7);        /* until the tab stop               */
  351.             break;
  352.  
  353.           case '\r':                    /* carriage return                  */
  354.             break;                      /* kill them off                    */
  355.  
  356.           case '\n':                    /* newline                          */
  357.             break;                      /* kill them too                    */
  358.  
  359.           case ' ':                     /* for spaces,                      */
  360.             work[to++] = c;             /* copy the character               */
  361.             break;
  362.  
  363.           default:                      /* for data,                        */
  364.             work[to] = c;               /* copy the character               */
  365.             i = to++;                   /* and save position                */
  366.             break;
  367.         }                               /* end switch                       */
  368.     }                                   /* end while                        */
  369.     work[to] = '\0';                    /* insure terminator                */
  370.     return(i+1);                        /* return data count                */
  371.  
  372. }                                       /* end detab                        */
  373.  
  374. /****************************************************************************/
  375. /*                                                                          */
  376. /* Process a program line, according to its type.                           */
  377. /*                                                                          */
  378. /****************************************************************************/
  379.  
  380. process(style,out,in,fp)
  381. int     style;
  382. char    in[];
  383. char    out[];
  384. FILE    *fp;
  385. {
  386.   switch(style)
  387.     {
  388.       case  BLANK:                      /* blank line                       */
  389.         fprintf(fp,"\n");               /* write a blank                    */
  390.         break;
  391.  
  392.       case  FCOMM:                      /* full width comment line          */
  393.         comm_solid(out);                /* fill to right edge of comment    */
  394.         fprintf(fp,"%s\n",out);         /* write the line                   */
  395.         break;
  396.  
  397.       case  LCOMM:                      /* left aligned comment line        */
  398.         comm_fix(out,in);               /* align right edge of comment      */
  399.         fprintf(fp,"%s\n",out);         /* write the line                   */
  400.         break;
  401.  
  402.       case  IFCOMM:                     /* indented full width comment line */
  403.         comm_block(out,in);             /* align right edge of comment      */
  404.         fprintf(fp,"%s\n",out);         /* write the line                   */
  405.         break;
  406.  
  407.       case  ICOMM:                      /* indented comment line            */
  408.         comm_fix(out,in);               /* align right edge of comment      */
  409.         fprintf(fp,"%s\n",out);         /* write the line                   */
  410.         break;
  411.  
  412.       case  CCOMM:                      /* continued comment                */
  413.         comm_sync(out,in);              /* sync up the line                 */
  414.         fprintf(fp,"%s\n",out);         /* write it                         */
  415.         break;
  416.  
  417.       case  CODE:                       /* normal code line                 */
  418.         code_left(out,in);              /* align left edge of code          */
  419.         comm_align(in,out);             /* align the comment                */
  420.         fprintf(fp,"%s\n",in);          /* write the line                   */
  421.         break;
  422.  
  423.       case  ICODE:                      /* code: indentation increase       */
  424.         align++;                        /* increase skip count              */
  425.         code_left(out,in);              /* align left edge of code          */
  426.         comm_align(in,out);             /* align the comment                */
  427.         fprintf(fp,"%s\n",in);          /* write the line                   */
  428.         break;
  429.  
  430.       case  OCODE:                      /* code: indentation decrease       */
  431.         if(align)                       /* if still indented,               */
  432.           align--;                      /* back up one                      */
  433.         code_left(out,in);              /* align left edge of code          */
  434.         comm_align(in,out);             /* align the comment                */
  435.         fprintf(fp,"%s\n",in);          /* write the line                   */
  436.         break;
  437.  
  438.       case  O2CODE:                     /* code: indentation decrease two   */
  439.         if(align)                       /* if still indented,               */
  440.           align--;                      /* back up one                      */
  441.         if(align)                       /* if still indented,               */
  442.           align--;                      /* back up another                  */
  443.         code_left(out,in);              /* align left edge of code          */
  444.         comm_align(in,out);             /* align the comment                */
  445.         fprintf(fp,"%s\n",in);          /* write the line                   */
  446.         break;
  447.  
  448.       case  ZCODE:                      /* code: indentation to zero        */
  449.         align = 0;                      /* back to margin                   */
  450.         code_left(out,in);              /* align left edge of code          */
  451.         comm_align(in,out);             /* align the comment                */
  452.         fprintf(fp,"%s\n",in);          /* write the line                   */
  453.         break;
  454.  
  455.     }                                   /* end switch                       */
  456. }                                       /* end process                      */
  457.